package com.zjx.mhxykey.util;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Point;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// 图片比较核心类
public class ImageComparator {

    /**
     * 简单像素比对 (返回相似度 0-1)
     * @param bmp1 第一张图片
     * @param bmp2 第二张图片
     * @return 相似度(0-1)
     */
    public static double compareByPixels(Bitmap bmp1, Bitmap bmp2) {
        if (bmp1 == null || bmp2 == null) return 0;

        // 确保尺寸相同
        Bitmap resizedBmp2 = Bitmap.createScaledBitmap(bmp2, bmp1.getWidth(), bmp1.getHeight(), true);

        int width = bmp1.getWidth();
        int height = bmp1.getHeight();
        int totalPixels = width * height;
        int matchingPixels = 0;

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (bmp1.getPixel(x, y) == resizedBmp2.getPixel(x, y)) {
                    matchingPixels++;
                }
            }
        }

        return (double) matchingPixels / totalPixels;
    }

    /**
     * 查找所有匹配的子图位置
     * @param source 源图像
     * @param template 模板图像
     * @param threshold 相似度阈值(0-1)
     * @param minDistance 最小匹配间距(避免重复检测相邻区域)
     * @return 所有匹配位置的列表
     */
    public static List<Point> findAllSubImages(Bitmap source, Bitmap template, double threshold, int minDistance) {
        List<Point> matches = new ArrayList<>();
        if (source == null || template == null) return matches;

        int sourceWidth = source.getWidth();
        int sourceHeight = source.getHeight();
        int templateWidth = template.getWidth();
        int templateHeight = template.getHeight();

        // 模板不能比源图大
        if (templateWidth > sourceWidth || templateHeight > sourceHeight) {
            return matches;
        }

        // 遍历所有可能的位置
        for (int y = 0; y <= sourceHeight - templateHeight; y++) {
            for (int x = 0; x <= sourceWidth - templateWidth; x++) {
                // 检查是否靠近已找到的匹配点
                boolean tooClose = false;
                for (Point p : matches) {
                    if (Math.abs(x - p.x) < minDistance && Math.abs(y - p.y) < minDistance) {
                        tooClose = true;
                        break;
                    }
                }
                if (tooClose) continue;

                // 截取当前区域的子图
                Bitmap subBitmap = Bitmap.createBitmap(
                        source, x, y, templateWidth, templateHeight);

                // 比较相似度
                double similarity = compareByHistogram(subBitmap, template);
                if (similarity >= threshold) {
                    matches.add(new Point(x, y));
                }
            }
        }

        return matches;
    }

    /**
     * 查找单个子图位置
     * @param source 源图像
     * @param template 模板图像
     * @param threshold 相似度阈值(0-1)
     * @return 第一个匹配位置，没有则返回null
     */
    public static Point findSubImage(Bitmap source, Bitmap template, double threshold) {
        List<Point> matches = findAllSubImages(source, template, threshold, 1);
        return matches.isEmpty() ? null : matches.get(0);
    }

    /**
     * 更高效的灰度直方图比较
     * @param bmp1 第一张图片
     * @param bmp2 第二张图片
     * @return 相似度(0-1)
     */
    public static double compareByHistogram(Bitmap bmp1, Bitmap bmp2) {
        if (bmp1 == null || bmp2 == null) return 0;

        // 调整到相同大小
        Bitmap resizedBmp2 = Bitmap.createScaledBitmap(bmp2, bmp1.getWidth(), bmp1.getHeight(), true);

        // 转换为灰度图
        Bitmap grayBmp1 = toGrayscale(bmp1);
        Bitmap grayBmp2 = toGrayscale(resizedBmp2);

        // 计算直方图
        int[] hist1 = calculateHistogram(grayBmp1);
        int[] hist2 = calculateHistogram(grayBmp2);

        // 计算直方图相似度
        return compareHistograms(hist1, hist2);
    }

    /**
     * 将图片转换为灰度图
     * @param bmp 原始图片
     * @return 灰度图片
     */
    private static Bitmap toGrayscale(Bitmap bmp) {
        Bitmap grayBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(grayBitmap);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        canvas.drawBitmap(bmp, 0, 0, paint);
        return grayBitmap;
    }

    /**
     * 计算灰度直方图
     * @param bmp 灰度图片
     * @return 直方图数组
     */
    private static int[] calculateHistogram(Bitmap bmp) {
        int[] histogram = new int[256];
        Arrays.fill(histogram, 0);

        int width = bmp.getWidth();
        int height = bmp.getHeight();

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int pixel = bmp.getPixel(x, y);
                int gray = Color.red(pixel); // 灰度图RGB值相同
                histogram[gray]++;
            }
        }

        return histogram;
    }

    /**
     * 比较两个直方图的相似度
     * @param hist1 第一个直方图
     * @param hist2 第二个直方图
     * @return 相似度(0-1)
     */
    private static double compareHistograms(int[] hist1, int[] hist2) {
        double sum1 = 0, sum2 = 0, sumSq = 0;

        for (int i = 0; i < hist1.length; i++) {
            sum1 += hist1[i];
            sum2 += hist2[i];
        }

        double avg1 = sum1 / hist1.length;
        double avg2 = sum2 / hist2.length;

        double covariance = 0;
        double variance1 = 0, variance2 = 0;

        for (int i = 0; i < hist1.length; i++) {
            double diff1 = hist1[i] - avg1;
            double diff2 = hist2[i] - avg2;

            covariance += diff1 * diff2;
            variance1 += diff1 * diff1;
            variance2 += diff2 * diff2;
        }

        if (variance1 == 0 || variance2 == 0) {
            return 0;
        }

        return covariance / Math.sqrt(variance1 * variance2);
    }

    public static void main(String[] args) {
        Bitmap sourceBitmap = null;
        Bitmap templateBitmap = null;

        // 查找所有匹配项
        List<Point> allMatches = ImageComparator.findAllSubImages(
                sourceBitmap,
                templateBitmap,
                0.8,  // 相似度阈值
                10    // 最小间距(像素)
        );

// 查找第一个匹配项
        Point firstMatch = ImageComparator.findSubImage(
                sourceBitmap,
                templateBitmap,
                0.8   // 相似度阈值
        );
    }
}